﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.OleDb;
using GemBox.ExcelLite;
using Newtonsoft.Json;
using System.Data;
using System.IO;
using log4net;
using System.Reflection;
using System.Configuration;

namespace iMall.AtoZ.Helper
{
    public class AtoZUtility
    {
        public static OrderInfoEnity GetOrderInfoEntityByOrderID(string orderID, string merchant, Dictionary<string, string> mapping)
        {
            OrderInfoEnity orderInfo = null;
            string sql = string.Format("select * from OrderInfo where OrderID='{0}' and Merchant='{1}'", orderID, merchant);

            DataSet ds = DALFactory.ExecuteSQLDataSet(sql);

            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                orderInfo = GetOrderInfoEnityFromDataRow(ds.Tables[0].Rows[0], mapping);
            }

            return orderInfo;
        }

        public static OrderInfoEnity GetOrderInfoEnityFromDataRow ( DataRow dr)
        {
            OrderInfoEnity orderInfo = new OrderInfoEnity();
            foreach ( DataColumn key in dr.Table.Columns)
            {
                string value = dr[key.ColumnName].ToString();
                orderInfo.SetValue(key.ColumnName, value);
            }

            return orderInfo;
        }

        public static OrderInfoEnity GetOrderInfoEnityFromDataRow(DataRow dr, Dictionary<string, string> mapping)
        {
            OrderInfoEnity orderInfo = new OrderInfoEnity();
            foreach (string key in mapping.Values)
            {
                string value = dr[key].ToString();
                orderInfo.SetValue(key, value);
            }

            return orderInfo;
        }

        public static OrderInfoEnity GetOrderInfoEnity(DataRow data, DataRow header, Dictionary<string, string> mapping)
        {
            int total = data.ItemArray.Count<object>();
            total = (mapping.Count < total) ? mapping.Count : total;
            int headCount = header.ItemArray.Count<object>();
            OrderInfoEnity entity = new OrderInfoEnity();
            string json = string.Empty;
            List<string> fields = new List<string>();

            foreach (var v in mapping.Values)
            {
                fields.Add(v);
            }
            for (int i = 0; i < total; i++)
            {
                string key = string.Empty;
                string h = (i < headCount) ? header[i].ToString() : "";
                if (!mapping.ContainsKey(h))
                {
                    key = fields[i];
                }
                else
                {
                    key = mapping[h];
                }
                string value = (data[i] == null) ? "" : data[i].ToString();
                if (value.Length < 1)
                {
                    continue;
                }
                entity.SetValue(key, value);
            }

            return entity;
        }

        public static OrderInfoEnity GetOrderInfoEnity(ExcelRow data, ExcelRow header, Dictionary<string, string> mapping)
        {
            OrderInfoEnity entity = null;
            int total = (header.Cells.LastColumnIndex < mapping.Count) ? header.Cells.LastColumnIndex : mapping.Count;
            string product = string.Empty;
            string json = string.Empty;
            for (int i = 0; i < total; i++)
            {
                if (header.Cells[i].Value == null && data.Cells[i].Value != null)
                {
                    product = data.Cells[i].Value.ToString();
                }


                if (header.Cells[i].Value == null || data.Cells[i].Value == null)
                {
                    continue;
                }

                string key = mapping[header.Cells[i].Value.ToString()];
                string value = data.Cells[i].Value.ToString();
                if (json.Length > 0)
                {
                    json += string.Format(",\"{0}\":\"{1}\"", key, value);
                }
                else
                {
                    json += string.Format("\"{0}\":\"{1}\"", key, value);
                }
            }
            json = String.Format("{{{0}}}", json);
            entity = JsonConvert.DeserializeObject<OrderInfoEnity>(json);
            entity.Product = product;

            return entity;
        }

        public static string GetInserSql(string table, object obj)
        {
            string sql = string.Empty;
            PropertyInfo[] propertyInfos = obj.GetType().GetProperties();
            string fields = string.Empty;
            string values = string.Empty;

            foreach (PropertyInfo pi in propertyInfos)
            {
                string ptn = pi.PropertyType.Name;

                if (pi.Name == "ID")
                {
                    continue;
                }

                if (fields.Length > 0)
                {
                    fields += ",";
                }
                fields += string.Format("[{0}]", pi.Name);

                if (values.Length > 0)
                {
                    values += ",";
                }

                object value = pi.GetValue(obj, null) ?? "";
                if (ptn == typeof(int).Name || ptn == typeof(short).Name || ptn == typeof(long).Name ||
                    ptn == typeof(Single).Name || ptn == typeof(float).Name || ptn == typeof(decimal).Name ||
                    ptn == typeof(double).Name || ptn == typeof(byte).Name || ptn == typeof(sbyte).Name)
                {
                    values += value.ToString();
                }
                else
                {
                    values += string.Format("'{0}'", value.ToString());
                }
            }
            sql = string.Format("insert into {0} ({1}) values({2})", table, fields, values);
            return sql;
        }

        public static string GetUpdateSql(string table, object obj)
        {
            string sql = string.Empty;
            string set = string.Empty;
            string id = string.Empty;
            PropertyInfo[] propertyInfos = obj.GetType().GetProperties();
            foreach (PropertyInfo pi in propertyInfos)
            {
                string ptn = pi.PropertyType.Name;

                if (pi.Name == "ID")
                {
                    id = pi.GetValue(obj, null).ToString();
                    continue;
                }

                if (set.Length > 1)
                {
                    set += ",";
                }

                if (ptn == typeof(int).Name || ptn == typeof(short).Name || ptn == typeof(long).Name ||
                    ptn == typeof(Single).Name || ptn == typeof(float).Name || ptn == typeof(decimal).Name ||
                    ptn == typeof(double).Name || ptn == typeof(byte).Name || ptn == typeof(sbyte).Name)
                {
                    set += string.Format("[{0}]={1}", pi.Name, pi.GetValue(obj, null) ?? "");
                }
                else
                {
                    set += string.Format("[{0}]='{1}'", pi.Name, pi.GetValue(obj, null) ?? "");
                }
            }

            sql = string.Format("update {0} set {1} where id={2}", table, set, id);

            return sql;
        }

        public static void SetObjPropertyValue(object obj, string field, string value)
        {
            PropertyInfo pi = obj.GetType().GetProperty(field.Trim());
            if ( pi == null )
            {
                foreach ( PropertyInfo item in obj.GetType().GetProperties() )
                {
                    if(string.Compare(item.Name,field,true)==0)
                    {
                        pi = item;
                    }
                }
            }
            string pt = pi.PropertyType.FullName;
            object objValue = new object();

            if (pt == typeof(int).FullName || pt == typeof(Int32).FullName)
            {
                objValue = Convert.ToInt32(value);
            }
            else if (pt == typeof(float).FullName || pt == typeof(Single).FullName)
            {
                objValue = Convert.ToSingle(value);
            }
            else if (pt == typeof(double).FullName || pt == typeof(Double).FullName)
            {
                objValue = Convert.ToDouble(value);
            }
            else if (pt == typeof(decimal).FullName || pt == typeof(Decimal).FullName)
            {
                objValue = Convert.ToDecimal(value);
            }
            else if (pt == typeof(short).FullName || pt == typeof(Int16).FullName)
            {
                objValue = Convert.ToInt16(value);
            }
            else if (pt == typeof(long).FullName || pt == typeof(Int64).FullName)
            {
                objValue = Convert.ToInt64(value);
            }
            else if (pt == typeof(DateTime).FullName)
            {
                objValue = Convert.ToDateTime(value);
            }
            else
            {
                objValue = value;
            }
            pi.SetValue(obj, objValue, null);
        }

        public static ILog Logging
        {
            get
            {
                string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"bin\log4net.config");
                log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(file));

                return LogManager.GetLogger("AtoZLog");
            }
        }

        public static DbAccessType DbType
        {
            get
            {
                int type = Convert.ToInt32(ConfigurationManager.AppSettings["dbtype"]);
                if (type == 1)
                {
                    return DbAccessType.Sql;
                }
                else
                {
                    return DbAccessType.Access;
                }
            }
        }
    }

    public enum DbAccessType
    {
        Sql = 1,
        Access = 2,
    }
}